/**
 * 项目名称（软件名称）：忠旺机械物资管理系统(mms)
 * 研发设计单位：忠旺机械设备制造有限公司机械设计院智能控制设计科设计与研发。
 * 版权所有：忠旺机械设备制造有限公司
 * 注：本项目的一切技术专利，使用规范归解释权由忠旺机械设备制造有限公司所有。
 * 软件版本：Ver 1.0.0
 * 文件路径：com.zhongwang.mms.module.purchase.service
 * 创建时间：2020年04月24日 18时12分
 **/
package com.zhongwang.mms.module.purchase.service;

import com.zhongwang.mms.base.BaseService;
import com.zhongwang.mms.common.ImportCallBack;
import com.zhongwang.mms.common.JsonResult;
import com.zhongwang.mms.gen.entity.PCheckDetail;
import com.zhongwang.mms.gen.entity.PInventory;
import com.zhongwang.mms.gen.entity.User;
import com.zhongwang.mms.module.purchase.dao.PurCheckDao;
import com.zhongwang.mms.module.purchase.dao.PurAdjustDao;
import com.zhongwang.mms.module.purchase.dao.PurPInventoryDao;
import com.zhongwang.mms.module.purchase.dao.PurChangeDao;
import com.zhongwang.mms.module.purchase.excelListener.PCheckDetailListener;
import com.zhongwang.mms.module.purchase.model.VWProject;
import com.zhongwang.mms.module.purchase.model.adjust.PAdjustModel;
import com.zhongwang.mms.module.purchase.model.check.*;
import com.zhongwang.mms.module.system.util.GetDateTimeService;
import com.zhongwang.mms.util.FileUtils;
import com.zhongwang.mms.util.ShiroUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName： CheckService
 * @Description： 盘点业务逻辑层
 * @Author： 徐一贺
 * @Date： 2020/4/24 18:12
 * @Version： V1.0
 **/
@Log4j2
@Service
public class PurCheckService extends BaseService {

    @Autowired
    private PurCheckDao purCheckDao;
    @Autowired
    private PurPInventoryDao purPInventoryDao;
    @Autowired
    private PurChangeDao purChangeDao;
    @Autowired
    private GetDateTimeService getDateTimeService;
    @Autowired
    private PurAdjustService purAdjustService;
    @Autowired
    private PurAdjustDao purAdjustDao;

    @Value("${user.upload.path}")
    private String uploadPath;
    private String msg = "";

    /**
     * @FunctionName: planList
     * @Description: 盘点计划列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/24 19:08
     * @Phone: 18241927380
     * @Param: [param] 检索参数
     * @Return: com.zhongwang.mms.common.JsonResult 列表数据
     * @Version: 1.0.0
     */
    public List<PCheckPlanModel> findPlanList(PCheckPlanQueryModel param) {
//        String rangeDate = param.getCpnDateTimeRange();
//        try {
//            if (rangeDate != null && !rangeDate.equals("")) {
//                param.setCpnStart(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(rangeDate.substring(0, rangeDate.indexOf("-")).replace('.', '/') + " 00:00:00"));
//                param.setCpnEnd(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(rangeDate.substring(rangeDate.indexOf("-") + 1).replace('.', '/') + " 23:59:59"));
//            }
//        } catch (ParseException e) {
//            e.printStackTrace();
//            log.error(e.getMessage());
//        }
        return purCheckDao.findPlanList(param);
    }


    /**
     * @FunctionName: planSave
     * @Description: 保存计划
     * @Author: 徐一贺
     * @CreateDate: 2020/4/25 10:23
     * @Phone: 18241927380
     * @Param: [param] 保存内容
     * @Return: [boolean] 返回结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean planSave(PCheckPlanModel param) {
        try {
            //如果为空则插入盘点计划数据
            if (null == param.getCpnId()) {
                param.setCpnCode(generateIPCOrderCode());
                param.setCpnStatus(1);
                param.setCpnPlanStatus(1);
                param.setCpnResStatus(1);
                param.setCpnAdjStatus(1);
                param.setCpnPalStatus(1);
                param.setCpnDate(new Date());
                param.setCpnMakerId(ShiroUtils.getUser().getId());
                purCheckDao.insertCheckPlanSelective(param);
                logService.saveLog("新增盘点计划", "盘点计划编号：" + param.getCpnCode());
            }
            //如果不为空则更新盘点计划数据
            else {
                PCheckPlanModel beforePCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(param.getCpnId());
                purCheckDao.updateCheckPlanSelectiveByPrimaryKey(param);
                PCheckPlanModel afterPCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(param.getCpnId());
                logService.saveLog("更新盘点计划", beforePCheckPlanModel, afterPCheckPlanModel);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: generateIPCOrderCode
     * @Description: 获取盘点计划编号
     * @Author: 徐一贺
     * @CreateDate: 2020/4/25 10:44
     * @Phone: 18241927380
     * @Param:
     * @Return: [newGenerateIPCOrderCode] 盘点计划编号
     * @Version: 1.0.0
     */
    private String generateIPCOrderCode() {
        String newGenerateIPCOrderCode = "";
        //获取最后编码
        String lastIPCOrderCode = purCheckDao.findLastIPCOrderCode();
        //获取当前时间简码
        String datetimeCode = new SimpleDateFormat("yyMMdd").format(new Date());
        Integer sn = 0;
        if (null != lastIPCOrderCode && lastIPCOrderCode.length() > 0) {
            //获取外购件库最新最后的入库单号
            sn = Integer.parseInt(lastIPCOrderCode.substring(9));
        }
        if (null == lastIPCOrderCode || lastIPCOrderCode.length() == 0) {
            newGenerateIPCOrderCode = "IPC" + new SimpleDateFormat("yyMMdd").format(new Date()) + "001";
        } else if (!lastIPCOrderCode.substring(3, 9).equals(datetimeCode)) {
            newGenerateIPCOrderCode = "IPC" + new SimpleDateFormat("yyMMdd").format(new Date()) + "001";
        } else {
            newGenerateIPCOrderCode = "IPC" + new SimpleDateFormat("yyMMdd").format(new Date()) + String.format("%03d", (sn + 1));
        }
        return newGenerateIPCOrderCode;
    }

    /**
     * @FunctionName: planRemove
     * @Description: 删除（逻辑）盘点计划
     * @Author: 徐一贺
     * @CreateDate: 2020/4/25 11:30
     * @Phone: 18241927380
     * @Param: [param] 盘点计划主键
     * @Return: [boolean] 删除结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean planRemove(PCheckPlanModel param) {
        try {
            param.setCpnStatus(0);
            purCheckDao.updateCheckPlanSelectiveByPrimaryKey(param);
            PCheckPlanModel removePCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(param.getCpnId());
            logService.saveLog("删除盘点计划", "删除的盘点计划编号是：" + removePCheckPlanModel.getCpnCode());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: planRemove
     * @Description: 提交盘点计划
     * @Author: 徐一贺
     * @CreateDate: 2020/4/25 11:30
     * @Phone: 18241927380
     * @Param: [param] 盘点计划主键
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean planSubmit(PCheckPlanModel param) {
        try {
//            param.setCpnStatus(2);
            param.setCpnPlanStatus(3);
            param.setCpnResStatus(2);
            purCheckDao.updateCheckPlanSelectiveByPrimaryKey(param);
            PCheckPlanModel removePCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(param.getCpnId());
            logService.saveLog("提交盘点计划", "提交的盘点计划编号是：" + removePCheckPlanModel.getCpnCode());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: planRevoke
     * @Description: 撤销盘点计划
     * @Author: 徐一贺
     * @CreateDate: 2020/4/25 11:30
     * @Phone: 18241927380
     * @Param: [param] 盘点计划主键
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult planRevoke(PCheckPlanModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            Integer checkCount = purCheckDao.getCheckDetailCheckCountByCdlCpnId(param.getCpnId());
            if (checkCount > 0) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg("有盘点结果已经进行盘点，不可撤销！");
            } else {
                param.setCpnPlanStatus(2);
                param.setCpnResStatus(1);
                purCheckDao.updateCheckPlanSelectiveByPrimaryKey(param);
                PCheckPlanModel removePCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(param.getCpnId());
                logService.saveLog("撤销盘点计划", "撤销的盘点计划编号是：" + removePCheckPlanModel.getCpnCode());
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
                jsonResult.setMsg("撤销成功！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("撤销失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: findDetailList
     * @Description: 根据盘点计划编码获取盘点明细列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/24 19:07
     * @Phone: 18241927380
     * @Param: [param] 检索参数
     * @Return: com.zhongwang.mms.common.JsonResult 列表数据
     * @Version: 1.0.0
     */
    public List<PCheckDetailModel> findDetailList(PCheckDetailQueryModel param) {
        return purCheckDao.findDetailList(param);
    }

    /**
     * @FunctionName: getCheckPlanByPK
     * @Description: 根据主键获取盘点计划
     * @Author: 徐一贺
     * @CreateDate: 2020/4/25 15:28
     * @Phone: 18241927380
     * @Param: [cpnId] 主键
     * @Return: [PCheckPlanModel] 盘点计划
     * @Version: 1.0.0
     */
    public PCheckPlanModel getCheckPlanByPK(Integer cpnId) {
        return purCheckDao.getPCheckPlanByByPrimaryKey(cpnId);
    }

    /**
     * @FunctionName: detailCreate
     * @Description: 根据传过来的库存主键创建盘点明细
     * @Author: 徐一贺
     * @CreateDate: 2020/4/24 19:07
     * @Phone: 18241927380
     * @Param: [param] 前端传递过来的参数 盘点计划编号和库存信息主键
     * @Return: com.zhongwang.mms.common.JsonResult 结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult detailCreate(PCheckDetailQueryModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            //获取库存列表
            List<PInventory> pInventoryList = purPInventoryDao.findInventoryListByityIds(param.getItyIds());
            Set<PInventory> existPInventorySet = new HashSet<>();
            PCheckPlanModel pCheckPlanModel = purCheckDao.getPCheckPlanByByCpnCode(param.getCpnCode());
            List<PCheckDetailModel> pCheckDetailModelList = purCheckDao.findDetailListByCdlCpnId(pCheckPlanModel.getCpnId());
            List<String> warningMessageList = new ArrayList<String>();
            for (PInventory pInventory : pInventoryList) {
                for (PCheckDetailModel testModel : pCheckDetailModelList) {
                    if (testModel.getCdlItyId().equals(pInventory.getItyId())) {
                        warningMessageList.add("选中的物料描述为【" + pInventory.getItyMatDesc() + "】的库存信息已经添加进明细表中。");
                        existPInventorySet.add(pInventory);
                    }
                }
            }
            for (PInventory existPInventory:existPInventorySet) {
                pInventoryList.remove(existPInventory);
            }
            //验证当前盘点计划状态是否是已执行
            if (pCheckPlanModel.getCpnPlanStatus().equals(1)) {
                //创建只有主键和盘点计划状态的模型，只为更新状态使用。
                PCheckPlanModel updateCpnPlanStatusModel = new PCheckPlanModel();
                updateCpnPlanStatusModel.setCpnId(pCheckPlanModel.getCpnId());
                updateCpnPlanStatusModel.setCpnPlanStatus(2);
                updateCpnPlanStatusModel.setCpnStatus(2);
                purCheckDao.updateCheckPlanSelectiveByPrimaryKey(updateCpnPlanStatusModel);
            }
            for (PInventory pInventory : pInventoryList) {
                PCheckDetailModel pCheckDetailModel = new PCheckDetailModel();
                pCheckDetailModel.setCdlMatDesc(pInventory.getItyMatDesc());
                pCheckDetailModel.setCdlMatCode(pInventory.getItySapCode());
                pCheckDetailModel.setCdlUnit(pInventory.getItyNumUnit());
                pCheckDetailModel.setCdlPrice(pInventory.getItyPrice());
                pCheckDetailModel.setCdlTrackCode(pInventory.getItyTrackCode());
                pCheckDetailModel.setCdlProName(pInventory.getItyProName());
                pCheckDetailModel.setCdlProCode(pInventory.getItyProCode());
                pCheckDetailModel.setCdlWhiId(pInventory.getItyWhiId());
                pCheckDetailModel.setCdlPosition(pInventory.getItyPosition());
                pCheckDetailModel.setCdlBookkeepingDate(pInventory.getItyBookkeepingDate());
                pCheckDetailModel.setCdlStockType(pInventory.getItyStockType());
                pCheckDetailModel.setCdlCpnId(pCheckPlanModel.getCpnId());
                pCheckDetailModel.setCdlItyId(pInventory.getItyId());
                pCheckDetailModel.setCdlStatus(1);
                pCheckDetailModel.setCdlItyNum(pInventory.getItyNum());
                purCheckDao.insertCheckDetailSelective(pCheckDetailModel);
            }
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            if (warningMessageList.size() > 0) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg(warningMessageList.toString().replace(",","<br>"));
            } else {
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
                jsonResult.setMsg("添加明细成功！");
            }
            logService.saveLog("添加盘点明细", "被添加盘点明细的盘点计划编号是：" + param.getCpnCode());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("添加明细失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: detailRemove
     * @Description: 删除（物理）盘点明细
     * @Author: 徐一贺
     * @CreateDate: 2020/4/25 11:30
     * @Phone: 18241927380
     * @Param: [param] 盘点明细主键
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean detailRemove(PCheckDetailModel param) {
        try {
            PCheckDetailModel pCheckDetailModel = purCheckDao.getPCheckDetailByPrimaryKey(param.getCdlId());
            purCheckDao.deleteCheckDetailByPrimaryKey(param.getCdlId());
            if (purCheckDao.getCheckDetailCountByCdlCpnId(pCheckDetailModel.getCdlCpnId()) == 0) {
                PCheckPlanModel pCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(pCheckDetailModel.getCdlCpnId());
                pCheckPlanModel.setCpnPlanStatus(1);
                pCheckPlanModel.setCpnStatus(1);
                purCheckDao.updateCheckPlanSelectiveByPrimaryKey(pCheckPlanModel);
            }
            logService.saveLog("【外购件】删除盘点明细", "被删除的盘点明细的物料描述是：" + pCheckDetailModel.getCdlMatDesc());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

//    /**
//     * @FunctionName: planStage
//     * @Description: 根据计划主键获取计划中各阶段状态
//     * @Author: 徐一贺
//     * @CreateDate: 2020/4/25 16:51
//     * @Phone: 18241927380
//     * @Param: [param] 计划主键
//     * @Return: com.zhongwang.mms.common.JsonResult
//     * @Version: 1.0.0
//     */
//    public PCheckPlanModel findPlanStageByCpnId(Integer cpnId) {
//        //1获取盘点计划状态
//        PCheckPlanModel checkPlanModel = checkDao.getPCheckPlanByByPrimaryKey(cpnId);
//        //2获取盘点结果
//        Map<String, Integer> paramMap = new HashMap<>();
//        paramMap.put("cpnId", cpnId);
//        //2.1获取盘点明细总数
//        paramMap.put("cdlStatus", null);
//        Integer checkDrtailCount = checkDao.getPCheckrtailCountByCpnId(paramMap);
//        //2.2获取盘点明细完成总数
//        paramMap.put("cdlStatus", 2);
//        Integer checkDrtailCompleteCount = checkDao.getPCheckrtailCountByCpnId(paramMap);
//        //2.3设置盘点结果状态
//        if (checkDrtailCount != 0 && checkDrtailCount.equals(checkDrtailCompleteCount)) {
//            checkPlanModel.setCheckResultStatus(3);
//        } else if (checkDrtailCount != 0) {
//            checkPlanModel.setCheckResultStatus(2);
//        } else {
//            checkPlanModel.setCheckResultStatus(1);
//        }
//        //3获取损益调整状态
//        checkPlanModel.setCheckAdjustStatus(1);
//        //4获取损益表状态
//        checkPlanModel.setIncomeStatementStatus(1);
//        return checkPlanModel;
//    }

    /**
     * @FunctionName: resultList
     * @Description: 盘点结果列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/24 20:15
     * @Phone: 18241927380
     * @Param: [param] 检索参数
     * @Return: com.zhongwang.mms.common.JsonResult 列表数据
     * @Version: 1.0.0
     */
    public List<PCheckDetailModel> findResultList(PCheckDetailQueryModel param) {
        return purCheckDao.findResultList(param);
    }

    /**
     * @FunctionName: adjustList
     * @Description: 盘点损益调整列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/29 09:28
     * @Phone: 18241927380
     * @Param: [param] 检索参数
     * @Return: com.zhongwang.mms.common.JsonResult 列表数据
     * @Version: 1.0.0
     */
    public List<PCheckDetailModel> findAdjustList(PCheckDetailQueryModel param) {
        return purCheckDao.findResultList(param);
    }

    /**
     * @FunctionName: resultCheck
     * @Description: 单条盘点
     * @Author: 徐一贺
     * @CreateDate: 2020/4/27 9:59
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    public boolean resultCheck(PCheckDetailQueryModel param) {
        try {
            PCheckDetailModel pCheckDetailModel = purCheckDao.getPCheckDetailByPrimaryKey(param.getCdlId());
            PCheckDetailModel checkDetailModel = new PCheckDetailModel();
            checkDetailModel.setCdlId(param.getCdlId());
            if (param.getCdlNum() > pCheckDetailModel.getCdlItyNum()) {
                checkDetailModel.setCdlCheckStatus(1);
            } else if (param.getCdlNum() < pCheckDetailModel.getCdlItyNum()) {
                checkDetailModel.setCdlCheckStatus(2);
            }
            checkDetailModel.setCdlNum(param.getCdlNum());
            checkDetailModel.setCdlPalVal(checkDetailModel.getCdlNum() - pCheckDetailModel.getCdlItyNum());
            checkDetailModel.setCdlStatus(2);
            purCheckDao.updatePCheckDetailSelectiveByPrimaryKey(checkDetailModel);
            logService.saveLog("【外购件】盘点明细", "被盘点的明细的物料描述是：" + pCheckDetailModel.getCdlMatDesc());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: checkAdd
     * @Description: 新增盘点
     * @Author: 徐一贺
     * @CreateDate: 2020/4/27 15:09
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    public boolean checkAdd(PCheckDetailModel param) {
        try {
            param.setCdlCpnId(purCheckDao.getPCheckPlanByByCpnCode(param.getCpnCode()).getCpnId());
            param.setCdlStatus(2);
            param.setCdlIsNewFlag(1);
            param.setCdlItyNum(0d);
            if (param.getCdlNum() > param.getCdlItyNum()) {
                param.setCdlCheckStatus(1);
            } else if (param.getCdlNum() < param.getCdlItyNum()) {
                param.setCdlCheckStatus(2);
            }
            param.setCdlPalVal(param.getCdlNum() - param.getCdlItyNum());
            purCheckDao.insertCheckDetailSelective(param);
            logService.saveLog("【外购件】新增盘点明细", "新增盘点明细入料描述：" + param.getCdlMatDesc());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: codeExist
     * @Description: 检测项目号是否存在
     * @Author: 徐一贺
     * @CreateDate: 2020/4/27 16:10
     * @Phone: 18241927380
     * @Param:
     * @Return:
     * @Version:
     */
    public Boolean codeExist(VWProject param) {
        param.setCeoNeedProCode(param.getCdlProCode());
        VWProject vwProject = purChangeDao.findVWProjectByCode(param);
        return vwProject != null;
    }

    /**
     * @FunctionName: planExport
     * @Description: 导出盘点计划
     * @Author: 徐一贺
     * @CreateDate: 2020/4/27 16:48
     * @Phone: 18241927380
     * @Param: [response]
     * @Return: void
     * @Version: 1.0.0
     */
    public void planExport(HttpServletResponse response, Integer cpnId) {
        List<PCheckDetailExcelModel> list = purCheckDao.findPCheckPlanByPrimaryKey(cpnId);
        PCheckPlanModel pCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(cpnId);
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        FileUtils.export(path, "盘点计划.xls", PCheckDetailExcelModel.class, "sheet1", list, response);
        logService.saveLog("【外购件库】导出盘点计划", "计划编号是：" + pCheckPlanModel.getCpnCode());
    }

    /**
     * @FunctionName: adjustExport
     * @Description: 导出盘点损益调整计划
     * @Author: 徐一贺
     * @CreateDate: 2020/4/29 10:11
     * @Phone: 18241927380
     * @Param: [response]
     * @Return: void
     * @Version: 1.0.0
     */
    public void adjustExport(HttpServletResponse response, Integer cpnId) {
        List<PCheckAdjustExcelModel> list = purCheckDao.findPCheckAdjustExcelBycdlCpnId(cpnId);
        PCheckPlanModel pCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(cpnId);
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        FileUtils.export(path, "盘点损益调整.xls", PCheckAdjustExcelModel.class, "sheet1", list, response);
        logService.saveLog("【外购件库】导出盘点损益调整", "计划编号是：" + pCheckPlanModel.getCpnCode());
    }

    /**
     * @FunctionName: resultClean
     * @Description: 清空该计划的盘点结果
     * @Author: 徐一贺
     * @CreateDate: 2020/4/28 10:37
     * @Phone: 18241927380
     * @Param: [param] 计划主键
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean resultClean(PCheckDetailQueryModel param) {
        try {
            List<PCheckDetailModel> pCheckDetailModelList = purCheckDao.findDetailListByCdlCpnId(param.getCdlCpnId());
            for (PCheckDetailModel pCheckDetailModel : pCheckDetailModelList) {
                if (pCheckDetailModel.getCdlIsNewFlag() == 1) {
                    purCheckDao.deleteCheckDetailByPrimaryKey(pCheckDetailModel.getCdlId());
                }
            }
            purCheckDao.resultClean(param.getCdlCpnId());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: resultImport
     * @Description: 盘点结果导入
     * @Author: 徐一贺
     * @CreateDate: 2020/4/28 12:36
     * @Phone: 18241927380
     * @Param: [file] 盘点结果Excel文件
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public String resultImport(MultipartFile file) {
        try {
            FileUtils.importExcel(file, PCheckDetailExcelModel.class, new PCheckDetailListener(purCheckDao, new ImportCallBack() {
                @Override
                public void onSuccess() {
                    msg = "导入完成";
                }

                @Override
                public void onWarning(List list) {
                    msg = "部份数据无法导入，请点击下载检查数据内容";
                    exportErrorExcel(list);
                }
            }));
            logService.saveLog("【外购件】导入盘点结果", "导入盘点结果成功！");

        } catch (IOException e) {
            return "导入失败";
        }
        return msg;
    }

    /**
     * 异常数据导出到Excel
     *
     * @param errorList
     */
    private void exportErrorExcel(List<PCheckDetailExcelModel> errorList) {
        if (errorList.size() <= 0) {
            return;
        }
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        FileUtils.genExcel(path, "checkError.xls", PCheckDetailExcelModel.class, "sheet1", errorList);
    }

    /**
     * @FunctionName: resultSubmit
     * @Description: 提交盘点结果
     * @Author: 徐一贺
     * @CreateDate: 2020/4/28 19:59
     * @Phone: 18241927380
     * @Param: [cdlCpnId] 主键
     * @Return: [boolean] 提交行为结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult resultSubmit(Integer cdlCpnId) {
        JsonResult jsonResult = new JsonResult();
        try {
            List<PCheckDetailModel> pCheckDetailModelList = purCheckDao.findDetailListByCdlCpnId(cdlCpnId);
            for (PCheckDetailModel pCheckDetailModel : pCheckDetailModelList) {
                if (pCheckDetailModel.getCdlNum() == null) {
                    jsonResult.setType(JsonResult.ResultType.ERROR);
                    jsonResult.setMsg("请填写所有盘点结果才可以进行提交！");
                    return jsonResult;
                }
            }
            PCheckPlanModel resultSubmitModel = new PCheckPlanModel();
            resultSubmitModel.setCpnId(cdlCpnId);
            resultSubmitModel.setCpnResStatus(3);
            resultSubmitModel.setCpnAdjStatus(2);
            purCheckDao.updateCheckPlanSelectiveByPrimaryKey(resultSubmitModel);
            PCheckPlanModel checkPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(cdlCpnId);
            logService.saveLog("【外购件】提交盘点结果", "提交盘点结果的计划编号是：" + checkPlanModel.getCpnCode());
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("提交盘点结果成功！");
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error(ex.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("提交盘点结果失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: adjustSubmit
     * @Description: 提交盘点损益调整
     * @Author: 徐一贺
     * @CreateDate: 2020/4/29 11:14
     * @Phone: 18241927380
     * @Param: [param] 盘点计划主键
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult adjustSubmit(Integer cdlCpnId) {
        JsonResult jsonResult = new JsonResult();
        try {
            List<PCheckDetailModel> pCheckDetailModelList = purCheckDao.findDetailListByCdlCpnId(cdlCpnId);

            for (PCheckDetailModel pCheckDetailModel : pCheckDetailModelList) {
                //生成库存调整申请 不含申请者信息与申请时间
                PAdjustmentApplyModel pAdjustmentApplyModel = new PAdjustmentApplyModel();
                pAdjustmentApplyModel = new PAdjustmentApplyModel();
                pAdjustmentApplyModel.setAjaNum(pCheckDetailModel.getCdlNum());
                pAdjustmentApplyModel.setAjaItyNum(pCheckDetailModel.getCdlItyNum());
                pAdjustmentApplyModel.setAjaItyStatus(1);
                pAdjustmentApplyModel.setAjaCpnId(pCheckDetailModel.getCdlCpnId());
                pAdjustmentApplyModel.setAjaItyId(pCheckDetailModel.getCdlItyId());
                pAdjustmentApplyModel.setAjaCdlId(pCheckDetailModel.getCdlId());
                purCheckDao.insertPAdjustmentApplyByPrimaryKey(pAdjustmentApplyModel);
            }
            //更改计划状态
            PCheckPlanModel resultSubmitModel = new PCheckPlanModel();
            resultSubmitModel.setCpnId(cdlCpnId);
            resultSubmitModel.setCpnAdjStatus(3);
            resultSubmitModel.setCpnPalStatus(2);
            purCheckDao.updateCheckPlanSelectiveByPrimaryKey(resultSubmitModel);
            PCheckPlanModel checkPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(cdlCpnId);
            logService.saveLog("【外购件】提交盘点损益调整", "提交盘点损益调整的计划编号是：" + checkPlanModel.getCpnCode());
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("提交盘点调整成功！");
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error(ex.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("提交盘点调整失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: adjustRevoke
     * @Description: 撤销盘点损益调整
     * @Author: 徐一贺
     * @CreateDate: 2020/4/29 11:14
     * @Phone: 18241927380
     * @Param: [param] 盘点计划主键
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult adjustRevoke(Integer cdlCpnId) {
        JsonResult jsonResult = new JsonResult();
        try {
            //检测损益表是否提交
            PCheckPlanModel checkPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(cdlCpnId);
            if (checkPlanModel.getCpnPalStatus().equals(3)) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg("损益表已提交，请撤销后，再撤销盘点损益调整。");
                return jsonResult;
            }
            //删除损益表相关数据
            purCheckDao.deletePAdjustmentApplyByAjaCpnId(cdlCpnId);
            //更改计划状态
            PCheckPlanModel resultSubmitModel = new PCheckPlanModel();
            resultSubmitModel.setCpnId(cdlCpnId);
            resultSubmitModel.setCpnAdjStatus(2);
            resultSubmitModel.setCpnPalStatus(1);
            purCheckDao.updateCheckPlanSelectiveByPrimaryKey(resultSubmitModel);

            logService.saveLog("【外购件】撤销盘点损益调整", "撤销盘点损益调整的计划编号是：" + checkPlanModel.getCpnCode());
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error(ex.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("损益表已提交，请撤销后，再撤销盘点损益调整。");
            return jsonResult;
        }
        jsonResult.setType(JsonResult.ResultType.SUCCESS);
        jsonResult.setMsg("撤销盘点损益调整成功。");
        return jsonResult;
    }

    /**
     * @FunctionName: resultRevoke
     * @Description: 撤销盘点结果
     * @Author: 徐一贺
     * @CreateDate: 2020/4/28 19:59
     * @Phone: 18241927380
     * @Param: [cdlCpnId] 主键
     * @Return: [boolean] 撤销行为结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean resultRevoke(Integer cdlCpnId) {
        try {
            PCheckPlanModel checkPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(cdlCpnId);
            PCheckPlanModel resultRevokeModel = new PCheckPlanModel();
            if (checkPlanModel.getCpnAdjStatus() == 3) {
                return false;
            }
            resultRevokeModel.setCpnId(cdlCpnId);
            resultRevokeModel.setCpnResStatus(2);
            resultRevokeModel.setCpnAdjStatus(1);
            purCheckDao.updateCheckPlanSelectiveByPrimaryKey(resultRevokeModel);
            logService.saveLog("【外购件】撤销盘点结果", "撤销盘点结果的计划编号是：" + checkPlanModel.getCpnCode());
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error(ex.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: adjustEdit
     * @Description: 调整损益差和备注
     * @Author: 徐一贺
     * @CreateDate: 2020/4/29 11:02
     * @Phone: 18241927380
     * @Param: [param] 调整损益差和备注的参数
     * @Return: [JsonResult] 页面结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult adjustEdit(PCheckDetailModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            if (param.getCdlPalVal() == 0) {
                param.setCdlCheckStatus(null);
            } else if (param.getCdlPalVal() > 0) {
                param.setCdlCheckStatus(1);
            } else {
                param.setCdlCheckStatus(2);
            }
            purCheckDao.updatePCheckDetailPalValByPrimaryKey(param);
            logService.saveLog("【外购件】盘点损益调整", "");
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("调整成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("调整失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: palList
     * @Description: 获得盘点损益表列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/29 14:16
     * @Phone: 18241927380
     * @Param:
     * @Return:
     * @Version: 1.0.0
     */
    public List<PAdjustmentApplyModel> palList(PAdjustmentApplyModel param) {
        return purCheckDao.selectPAdjustmentApplyModelSelectiveByCdlCpnId(param);
    }

    /**
     * @FunctionName: palSumList
     * @Description: 获取汇总表信息
     * @Author: 徐一贺
     * @CreateDate: 2020/4/29 15:58
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    public List<PAdjustmentApplyModel> palSumList(PAdjustmentApplyModel param) {
        return purCheckDao.palSumList(param);
    }

    /**
     * @FunctionName: palsubmit
     * @Description: 提交损益表
     * @Author: 徐一贺
     * @CreateDate: 2020/5/4 8:00
     * @Phone: 18241927380
     * @Param: [param] 参数
     * @Return: [JsonResult] 提交结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult palSubmit(PAdjustmentApplyModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            //获取损益表信息
            List<PAdjustmentApplyModel> adjustmentApplyModelList = purCheckDao.selectPAdjustmentApplyModelSelectiveByPrimaryKeys(param.getAjaIds());
            //遍历生成调整申请单
            for (PAdjustmentApplyModel pAdjustmentApplyModel : adjustmentApplyModelList) {
                PAdjustModel pAdjustModel = new PAdjustModel();
                pAdjustModel.setAdjAjaId(pAdjustmentApplyModel.getAjaId());
                pAdjustModel.setAdjType(2);
                pAdjustModel.setAdjStatus(2);
                pAdjustModel.setAdjNum(pAdjustmentApplyModel.getAjaNum());
                PInventory pInventory = purPInventoryDao.selectByPrimaryKey(pAdjustmentApplyModel.getAjaItyId());
                //如果不为空则是由库存选择来的盘点
                if (null != pInventory) {
                    pAdjustModel.setAdjMatDesc(pInventory.getItyMatDesc());
                    pAdjustModel.setAdjMatCode(pInventory.getItyMatCode());
                    pAdjustModel.setAdjUnit(pInventory.getItyNumUnit());
                    pAdjustModel.setAdjPrice(pInventory.getItyPrice());
                    pAdjustModel.setAdjTrackCode(pInventory.getItyTrackCode());
                    pAdjustModel.setAdjProCode(pInventory.getItyProCode());
                    pAdjustModel.setAdjProName(pInventory.getItyProName());
                    pAdjustModel.setAdjWhiId(pInventory.getItyWhiId());
                    pAdjustModel.setAdjPosition(pInventory.getItyPosition());
                    pAdjustModel.setAdjBookkeepingDate(pInventory.getItyBookkeepingDate());
                    pAdjustModel.setAdjSpec(pInventory.getItyRemark());
                    pAdjustModel.setAdjStockType(pInventory.getItyStockType());
                    pAdjustModel.setAdjNewFlag(0);
                    pAdjustModel.setAdjDValue(pAdjustmentApplyModel.getAjaNum() - pInventory.getItyNum());
                }
                //如果为空则是新增的盘点
                else {
                    PCheckDetailModel checkDetailModel = purCheckDao.getPCheckDetailByPrimaryKey(pAdjustmentApplyModel.getAjaCdlId());
                    pAdjustModel.setAdjMatDesc(checkDetailModel.getCdlMatDesc());
                    pAdjustModel.setAdjMatCode(checkDetailModel.getCdlMatCode());
                    pAdjustModel.setAdjUnit(checkDetailModel.getCdlUnit());
                    pAdjustModel.setAdjPrice(checkDetailModel.getCdlPrice());
                    pAdjustModel.setAdjTrackCode(checkDetailModel.getCdlTrackCode());
                    pAdjustModel.setAdjProCode(checkDetailModel.getCdlProCode());
                    pAdjustModel.setAdjProName(checkDetailModel.getCdlProName());
                    pAdjustModel.setAdjWhiId(checkDetailModel.getCdlWhiId());
                    pAdjustModel.setAdjPosition(checkDetailModel.getCdlPosition());
                    pAdjustModel.setAdjBookkeepingDate(checkDetailModel.getCdlBookkeepingDate());
                    pAdjustModel.setAdjSpec(checkDetailModel.getCdlRemark());
                    pAdjustModel.setAdjStockType(checkDetailModel.getCdlStockType());
                    pAdjustModel.setAdjNewFlag(1);
                    pAdjustModel.setAdjDValue(pAdjustmentApplyModel.getAjaNum());
                }
                pAdjustModel.setAdjReason(purCheckDao.getPCheckDetailByPrimaryKey(pAdjustmentApplyModel.getAjaCdlId()).getCdlRemark());
                pAdjustModel.setAdjCdlId(pAdjustmentApplyModel.getAjaCdlId());
                pAdjustModel.setAdjCode(purAdjustService.generateAdjCode());
                pAdjustModel.setAdjAppId(ShiroUtils.getUser().getId());
                pAdjustModel.setAdjAppDatetime(new Date());
                pAdjustModel.setAdjIdentity(2);
                pAdjustModel.setAdjItyId(pAdjustmentApplyModel.getAjaItyId());
                purAdjustDao.insertSelective(pAdjustModel);
                PAdjustmentApplyModel updateItyStatusModel = new PAdjustmentApplyModel();
                updateItyStatusModel.setAjaId(pAdjustmentApplyModel.getAjaId());
                updateItyStatusModel.setAjaItyStatus(2);
                updateItyStatusModel.setAjaAdjId(pAdjustModel.getAdjId());
                purCheckDao.updatePAdjustmentApplyModelAjaItyStatus(updateItyStatusModel);
                logService.saveLog("【外购件】创建调整申请", "根据盘点损益结果创建调整申请。");
            }
            PCheckPlanModel pCheckPlanModel = new PCheckPlanModel();
            pCheckPlanModel.setCpnId(param.getCdlCpnId());
            pCheckPlanModel.setCpnPalStatus(3);
            pCheckPlanModel.setCpnStatus(3);
            purCheckDao.updateCheckPlanSelectiveByPrimaryKey(pCheckPlanModel);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("提交成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("提交失败");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: detailRemoves
     * @Description: 批量删除
     * @Author: 徐一贺
     * @CreateDate: 2020/5/4 16:00
     * @Phone: 18241927380
     * @Param: [param] 批量删除参数
     * @Return: [JsonResult] 返回结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult detailRemoves(PCheckDetailModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            if (!param.getCdlIds().equals("")) {
                Integer cdlId = Integer.valueOf(param.getCdlIds().split(",")[0]);
                PCheckDetailModel pCheckDetailModel = purCheckDao.getPCheckDetailByPrimaryKey(cdlId);
                purCheckDao.deleteCheckDetailByPrimaryKeys(param.getCdlIds());
                if (purCheckDao.getCheckDetailCountByCdlCpnId(pCheckDetailModel.getCdlCpnId()) == 0) {
                    PCheckPlanModel pCheckPlanModel = purCheckDao.getPCheckPlanByByPrimaryKey(pCheckDetailModel.getCdlCpnId());
                    pCheckPlanModel.setCpnPlanStatus(1);
                    pCheckPlanModel.setCpnStatus(1);
                    purCheckDao.updateCheckPlanSelectiveByPrimaryKey(pCheckPlanModel);
                }
                logService.saveLog("【外购件】批量删除盘点明细", "批量删除盘点明细");
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
                jsonResult.setMsg("删除盘点明细成功。");
            } else {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg("请选择要被删除的盘点明细。");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("删除盘点明细失败。");
        }
        return jsonResult;
    }

}